package com.wjk.kylin.core.interceptor;

import com.wjk.kylin.core.filter.WrappedHttpServletRequest;
import com.wjk.kylin.core.filter.WrappedHttpServletResponse;
import com.wjk.kylin.core.utils.DateUtils;
import com.wjk.kylin.core.utils.IpUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.NamedThreadLocal;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.SimpleDateFormat;

/**
 * @author wangjkui
 * @description 拦截器
 * @date 2020/5/22
 */
@Slf4j
@Component
public class CustomHandlerInterceptor extends HandlerInterceptorAdapter {

    private static final ThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("ThreadLocal StartTime");

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        super.preHandle(request, response, handler);

        //===================================================================================
        if (log.isDebugEnabled()){
            long beginTime = System.currentTimeMillis();//1、开始时间
            startTimeThreadLocal.set(beginTime);		//线程绑定变量（该数据只有当前请求的线程可见）
            log.debug("开始计时: {}  URI: {}", new SimpleDateFormat("HH:mm:ss.SSS").format(beginTime), request.getRequestURI());
        }
        //===================================================================================

        //请求开始计时，单位毫秒
//        long startTime = System.currentTimeMillis();
//        request.setAttribute("startTime", startTime);
//
//        //请求信息
//        String remoteIp = IpUtils.getIpAddr(request);
//        String uri = request.getRequestURI();
//        String params = null;
//        if (request instanceof WrappedHttpServletRequest) {
//            try {
//                params = ((WrappedHttpServletRequest) request).getRequestParams();
//            } catch (IOException e) {
//                log.error("打印请求参数异常 {}", e.toString());
//            }
//        }
//
//        if (isExcludeUri(uri)) return true;
//
//        log.info(" ");//格式化
//        log.info("请求 ========> 接口：[{}],\t ip：[{}],\t 参数：[{}]", uri, remoteIp, params);

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        super.afterCompletion(request, response, handler, ex);

        //===================================================================================
        if (log.isDebugEnabled()){

            long beginTime = startTimeThreadLocal.get();//得到线程绑定的局部变量（开始时间）
            long endTime = System.currentTimeMillis(); 	//2、结束时间
            log.debug("计时结束：{}  耗时：{}  URI: {}  最大内存: {}m  已分配内存: {}m  已分配内存中的剩余空间: {}m  最大可用内存: {}m",
                    new SimpleDateFormat("HH:mm:ss.SSS").format(endTime), DateUtils.formatDateTime(endTime - beginTime),
                    request.getRequestURI(), Runtime.getRuntime().maxMemory()/1024/1024, Runtime.getRuntime().totalMemory()/1024/1024, Runtime.getRuntime().freeMemory()/1024/1024,
                    (Runtime.getRuntime().maxMemory()-Runtime.getRuntime().totalMemory()+Runtime.getRuntime().freeMemory())/1024/1024);
        }
        //===================================================================================

        //应答信息
//        String uri = request.getRequestURI();
//
//        //计算耗时,单位毫秒
//        long startTime = (Long) request.getAttribute("startTime");
//        long endTime = System.currentTimeMillis();
//        long executeTime = endTime - startTime;
//
//        String responseParams = null;
//        if (response instanceof WrappedHttpServletResponse) {
//            try {
//                WrappedHttpServletResponse wrappedHttpServletResponse = ((WrappedHttpServletResponse) response);
//                responseParams = wrappedHttpServletResponse.getResponseParams();
//                wrappedHttpServletResponse.flushToDest();
//            } catch (Exception e) {
//                log.error("获取应答参数异常 {}", e.toString());
//            }
//        }
//
//        if (isExcludeUri(uri)) return;
//
//        log.info("响应 ========> 接口：[{}],\t 耗时：[{}ms],\t 参数：[{}]", uri, executeTime, responseParams);
//        log.info(" ");//格式化
    }

    /**
     * 被排除打印的uri
     */
    private boolean isExcludeUri(String uri) {
        return uri.contains("sys/system/avatar")
                || uri.contains("sys/user/export")
                || uri.contains("sys/user/import");
    }
}
